﻿using DFGK_WMS.IRepository.IService;
using DFGK_WMS.Model.Enum;
using DFGK_WMS.Model.Models;
using NPOI.SS.Formula.Functions;
using SqlSugar;

namespace DFGK_WMS.Repository.Service
{
    public class RemoveInventoryService : BaseService, IRemoveInventoryService
    {
        public RemoveInventoryService(ISqlSugarClient cliet) : base(cliet)
        {

        }
        /// <summary>
        /// 获取移库可用仓位
        /// </summary>
        /// <param name="locationId">仓位id</param>
        /// <param name="toLogicalPartCode">逻辑分区编码</param>
        /// <param name="isPriorityFilling">true 深货有位  false整列全空</param>
        /// <param name="filterType">1同物料同批次 2同物料不同批次 3不限物料不限批次</param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public  dynamic GetRmoveEnableCell(int locationId, string toLogicalPartCode, bool isPriorityFilling , int filterType = 1)
        {
            TInventory inventory = _Client.Queryable<TInventory>().First(t => t.LocationId == locationId);
            if (inventory == null)
            {
                throw new Exception("移库ID错误");
            }
            var cellQuery = _Client.Queryable<TCell>();
            if (inventory.IsMultPallet == true)
            {
                toLogicalPartCode = "MultPallet";//花盘定死
            }    

            if (isPriorityFilling)
            {
                //同物料同批次  
                if (filterType == 1)
                {
                    //正常仓位
                    cellQuery.Where(
                               cell =>
                               SqlFunc.Subqueryable<TCell>()
                               .InnerJoin<TInventory>((c, inv) => c.Id == inv.LocationId)
                               .Where(
                                        (c, inv) => inv.MaterialKeyId == inventory.MaterialKeyId && inv.MaterialId == inventory.MaterialId && inv.Status == (int)EmInventoryStatus.Normal
                                       && c.DepthIndex > 0 && c.Status == (int)EmCellStatus.Normal && c.IsLock == false && inv.Status == (int)EmInventoryStatus.Normal && c.BusinessType == 0  
                                       && cell.LayerNo ==c.LayerNo  && cell.LineNo == c.LineNo && cell.ColumnNo == c.ColumnNo && cell.DepthIndex > c.DepthIndex

                                      ).Any()
                                   )
                     ;

                    //锁定仓位
                    cellQuery.Where(
                              cell =>
                              SqlFunc.Subqueryable<TCell>()
                              .InnerJoin<TInventory>((c, inv) => c.Id == inv.LocationId)
                              .Where(
                                       (c, inv) => c.DepthIndex > 0 && inv.MaterialId == inventory.MaterialId && inv.MaterialKeyId == inventory.MaterialKeyId
                                        && (c.Status != (int)EmCellStatus.Normal || c.IsLock == true || inv.Status != (int)EmInventoryStatus.Normal)
                                        && cell.LayerNo == c.LayerNo && cell.LineNo == c.LineNo && cell.ColumnNo == c.ColumnNo && cell.DepthIndex > c.DepthIndex
                              ).NotAny()
                    )
                    ;
                }
                else if (filterType == 2) //同物料不限批次 
                {
                    //正常仓位
                    cellQuery.Where(
                    cell =>
                    SqlFunc.Subqueryable<TCell>()
                               .InnerJoin<TInventory>((c, inv) => c.Id == inv.LocationId)
                               .Where(
                                        (c, inv) => c.DepthIndex > 0 && inv.MaterialId == inventory.MaterialId
                                       && c.Status == (int)EmCellStatus.Normal && c.IsLock == false && inv.Status == (int)EmInventoryStatus.Normal && c.BusinessType == 0
                                       && cell.LayerNo == c.LayerNo && cell.LineNo == c.LineNo && cell.ColumnNo == c.ColumnNo && cell.DepthIndex > c.DepthIndex
                                       ).Any()
                                   )
                     ;

                    //锁定仓位
                    cellQuery.Where(
                              cell =>
                              SqlFunc.Subqueryable<TCell>()
                              .InnerJoin<TInventory>((c, inv) => c.Id == inv.LocationId)
                              .Where(
                                       (c, inv) => c.DepthIndex > 0 && inv.MaterialId == inventory.MaterialId
                                       && (c.Status != (int)EmCellStatus.Normal || c.IsLock == true || inv.Status != (int)EmInventoryStatus.Normal)
                                       && cell.LayerNo == c.LayerNo && cell.LineNo == c.LineNo && cell.ColumnNo == c.ColumnNo && cell.DepthIndex > c.DepthIndex
                                       ).NotAny()
                                  )
                    ;
                }
                else  //不限物料不限批次
                {
                    //正常仓位
                    cellQuery.Where(
                               cell =>
                               SqlFunc.Subqueryable<TCell>()
                               .InnerJoin<TInventory>((c, inv) => c.Id == inv.LocationId)
                               .Where(
                                        (c, inv) => c.DepthIndex > 0 && c.Status == (int)EmCellStatus.Normal && c.IsLock == false && inv.Status == (int)EmInventoryStatus.Normal && c.BusinessType == 0
                                         && cell.LayerNo == c.LayerNo && cell.LineNo == c.LineNo && cell.ColumnNo == c.ColumnNo && cell.DepthIndex > c.DepthIndex
                                        ).Any()
                                   )
                     ;

                    //锁定仓位
                    cellQuery.Where(
                              cell =>
                              SqlFunc.Subqueryable<TCell>()
                              .InnerJoin<TInventory>((c, inv) => c.Id == inv.LocationId)
                              .Where(
                                       (c, inv) => c.DepthIndex > 0
                                        && (c.Status != (int)EmCellStatus.Normal || c.IsLock == true || inv.Status != (int)EmInventoryStatus.Normal)
                                        && cell.LayerNo == c.LayerNo && cell.LineNo == c.LineNo && cell.ColumnNo == c.ColumnNo && cell.DepthIndex > c.DepthIndex
                                        ).NotAny()
                                  )
                    ;
                }

                if (!string.IsNullOrEmpty(toLogicalPartCode))
                {
                    cellQuery.Where(t => t.LogicalPartCode == toLogicalPartCode);
                }
            }
            else
            {
                //cellQuery.Where(cell => cell.Status == (int)EmCellStatus.Normal && cell.FullStatus == 0 && cell.IsLock == false && cell.BusinessType == 0 && cell.HeightType >= inventory.RealHeightType);
                if (!string.IsNullOrEmpty(toLogicalPartCode))
                {
                    cellQuery.Where(t => t.LogicalPartCode == toLogicalPartCode);
                }
            }
            cellQuery.OrderBy("[HeightType] ASC,[LineNo] ASC,[DistanceValue] ASC,[LayerNO] ASC,[ColumnNO] ASC,[DepthIndex] DESC");

            var result = cellQuery.Select(t=>new 
            {
                ToWarehouseId = t.WhId,
                ToWarehouseCode = t.WhCode,
                ToWarehouseName = t.WhName,
                ToAreaId = t.AreaId,
                ToAreaCode = t.AreaCode,
                ToAreaName = t.AreaName,
                ToLocationId = t.Id,
                ToLocationName = t.Code,
                ToLocationCode = t.Name

            }).ToList();

            return result;

        }
    }
}
